package utils

/*
大数加法，只适用于浮点数
*/
func doBigFloatPlus(i1 []int8, d1 []int8, i2 []int8, d2 []int8) []int8 {
	if isNegative(i1) {
		if isNegative(i2) {
			//负数加负数
			i1, i2 = setPositive(i1), setPositive(i2)
			resI := bigIntegerPlus0(i1, i2)
			resD, carryBit := bigFloatPlus0(d1, d2)
			return setNegative(integerPlusFloat(resI, resD, carryBit))
		} else {
			//负数加正数
			i1 = setPositive(i1)
			resI := bigIntegerSub0(i2, i1)
			resD, carryBit := bigFloatSub0(d2, d1)
			return integerSubFloat(resI, resD, carryBit)
		}
	} else {
		if isNegative(i2) {
			//正数加负数
			i2 = setPositive(i2)
			resI := bigIntegerSub0(i1, i2)
			resD, carryBit := bigFloatSub0(d1, d2)
			return integerSubFloat(resI, resD, carryBit)
		} else {
			//正数加正数
			resI := bigIntegerPlus0(i1, i2)
			resD, carryBit := bigFloatPlus0(d1, d2)
			return integerPlusFloat(resI, resD, carryBit)
		}
	}
}

/*
大数减法，只适用于浮点数
*/
func doBigFloatSub(i1 []int8, d1 []int8, i2 []int8, d2 []int8) []int8 {
	if isNegative(i1) {
		if isNegative(i2) {
			//负数减负数
			i1, i2 = setPositive(i1), setPositive(i2)
			resI := bigIntegerSub0(i2, i1)
			resD, carryBit := bigFloatSub0(d2, d1)
			return integerSubFloat(resI, resD, carryBit)
		} else {
			//负数减正数
			i1 = setPositive(i1)
			resI := bigIntegerPlus0(i1, i2)
			resD, carryBit := bigFloatPlus0(d1, d2)
			return setNegative(integerPlusFloat(resI, resD, carryBit))
		}
	} else {
		if isNegative(i2) {
			//正数减负数
			i2 = setPositive(i2)
			resI := bigIntegerPlus0(i1, i2)
			resD, carryBit := bigFloatPlus0(d1, d2)
			return integerPlusFloat(resI, resD, carryBit)
		} else {
			//正数减正数
			resI := bigIntegerSub0(i1, i2)
			resD, carryBit := bigFloatSub0(d1, d2)
			return integerSubFloat(resI, resD, carryBit)
		}
	}
}

/*
大数乘法，只适用于浮点数
*/
func doBigFloatMultiply(i1 []int8, d1 []int8, i2 []int8, d2 []int8) []int8 {
	if isNegative(i1) {
		if isNegative(i2) {
			//负数乘负数
			return bigFloatMultiply0(setPositive(i1), d1, setPositive(i2), d2)
		} else {
			//负数乘正数
			return setNegative(bigFloatMultiply0(setPositive(i1), d1, i2, d2))
		}
	} else {
		if isNegative(i2) {
			//正数乘负数
			return setNegative(bigFloatMultiply0(i1, d1, setPositive(i2), d2))
		} else {
			//正数乘正数
			return bigFloatMultiply0(i1, d1, i2, d2)
		}
	}
}

/*
大数除法，只适用于浮点数
*/
func doBigFloatDivide(i1 []int8, d1 []int8, i2 []int8, d2 []int8, bit int) []int8 {
	if (isZero(i2) || isZero(setPositive(i2))) && isZero(d2) {
		panic("除数不能为零")
	}
	fLen := len(d1) - len(d2)
	bit = boolFunc(bit > maxBit, maxBit, bit)
	if isNegative(i1) {
		if isNegative(i2) {
			//负数除负数
			return bigFloatDivide0(setPositive(i1), d1, setPositive(i2), d2, fLen, bit)
		} else {
			//负数除正数
			return setNegative(bigFloatDivide0(setPositive(i1), d1, i2, d2, fLen, bit))
		}
	} else {
		if isNegative(i2) {
			//正数除负数
			return setNegative(bigFloatDivide0(i1, d1, setPositive(i2), d2, fLen, bit))
		} else {
			//正数除正数
			return bigFloatDivide0(i1, d1, i2, d2, fLen, bit)
		}
	}
}

/*
大数的小数部分加法，只适用于正浮点数的小数部分
*/
func bigFloatPlus0(n1 []int8, n2 []int8) ([]int8, bool) {
	l1, l2 := len(n1), len(n2)
	if l1 < l2 {
		return bigFloatPlus0(n2, n1)
	}
	n2 = appendTailZero(n2, l1-l2)
	res := bigIntegerPlus0(n1, n2)
	if len(res) > l1 {
		return res[1:], true
	} else {
		return res, false
	}
}

/*
大数的小数部分减法，只适用于正浮点数的小数部分
*/
func bigFloatSub0(n1 []int8, n2 []int8) ([]int8, bool) {
	l1, l2 := len(n1), len(n2)
	if l1 < l2 {
		n1 = appendTailZero(n1, l2-l1)
	} else {
		n2 = appendTailZero(n2, l1-l2)
	}
	if smallerThan(n1, n2) {
		return setNegative(bigIntegerSub0(n2, n1)), true
	} else {
		return bigIntegerSub0(n1, n2), false
	}
}

/*
大数乘法，只适用于正浮点数
*/
func bigFloatMultiply0(i1 []int8, d1 []int8, i2 []int8, d2 []int8) []int8 {
	floatLen := len(d1) + len(d2)
	multiplyRes := bigIntegerMultiply0(mergeFloatNoDot(i1, d1), mergeFloatNoDot(i2, d2))
	rLen := len(multiplyRes) + 1
	res := make([]int8, rLen)
	i, j := 0, 0
	for i < rLen-floatLen-1 {
		res[i] = multiplyRes[j]
		i++
		j++
	}
	res[i] = '.'
	i++
	for i < rLen {
		res[i] = multiplyRes[j]
		i++
		j++
	}
	return res
}

/*
大数除法，只适用于正浮点数
*/
func bigFloatDivide0(i1 []int8, d1 []int8, i2 []int8, d2 []int8, floatBit int, bit int) []int8 {
	n1 := mergeFloatNoDot(i1, d1)
	n2 := mergeFloatNoDot(i2, d2)
	n1 = appendTailZero(n1, bit)
	res, _ := bigIntegerDivide0(n1, n2)

	return floatDivide10(res, bit+floatBit)
}
